﻿#pragma once
#include <stdbool.h>
#include "Dispatcher.h"
#include "ChannelMap.h"
#include <pthread.h>
/*
	可以使用三种文件描述符监控方式，
	Dispatcher：1、epoll
				2、poll
				3、select
	DispatcherDate：
*/

// extern 使用其他文件中的全局变量
extern struct Dispatcher EpollDispatcher;
extern struct Dispatcher PollDispatcher;
extern struct Dispatcher SelectDispatcher;

// 处理该节点中的channel的方式
enum ElemType { ADD, DELETE, MODIFY };
// 定义任务队列的节点
struct ChannelElement
{
	int type;   // 如何处理该节点中的channel
	struct Channel* channel;//封装文件描述符
	struct ChannelElement* next;//指向下一节点
};
struct Dispatcher;

//
struct EventLoop
{
	bool isQuit;
	struct Dispatcher* dispatcher;
	void* dispatcherData;
	// 任务队列 头尾结点
	struct ChannelElement* head;
	struct ChannelElement* tail;
	// map 文件描述符 和 任务队列 的映射，下标即是文件描述符
	struct ChannelMap* channelMap;
	// 线程id, name, mutex
	pthread_t threadID;
	char threadName[32];
	pthread_mutex_t mutex;//保护任务队列
	int socketPair[2];  // 存储“本地通信”的 fd 通过socketpair 初始化，用来 主线程手动解除子线程 select  poll epoll 阻塞
};

// 初始化

struct EventLoop* eventLoopInit();//c语言里没有函数重载
struct EventLoop* eventLoopInitEx(const char* threadName);//指定线程名
// 启动反应堆模型
int eventLoopRun(struct EventLoop* evLoop);
// 处理别激活的文件fd
int eventActivate(struct EventLoop* evLoop, int fd, int event);
// 添加任务到任务队列
int eventLoopAddTask(struct EventLoop* evLoop, struct Channel* channel, int type);
// 处理任务队列中的任务
int eventLoopProcessTask(struct EventLoop* evLoop);
// 处理dispatcher中的节点
int eventLoopAdd(struct EventLoop* evLoop, struct Channel* channel);
int eventLoopRemove(struct EventLoop* evLoop, struct Channel* channel);
int eventLoopModify(struct EventLoop* evLoop, struct Channel* channel);
// 释放channel
int destroyChannel(struct EventLoop* evLoop, struct Channel* channel);
